package com.atguigu.gmall.juc.atomic;

import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * @author 陈昆昆
 * @version 1.0
 * @date 2020/6/1 23:12
 */
public class ABATest {
    public static void main(String[] args) {
        System.out.println("=========================ABA产生===============================");
        AtomicReference<Integer> atomicReference = new AtomicReference<>(100);
        new Thread(()->{
            atomicReference.compareAndSet(100,101);
            atomicReference.compareAndSet(101,100);
        },"t1").start();

        new Thread(()->{
            try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            boolean andSet = atomicReference.compareAndSet(100, 101);
            System.out.println(andSet+"---->"+atomicReference.get());
        },"t1").start();
        try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); }



        System.out.println("=========================ABA解决===============================");
        AtomicStampedReference<Integer> stampedReference = new AtomicStampedReference<>(100,1);
        new Thread(()->{
            try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
            int stamp = stampedReference.getStamp();
            System.out.println("t3--->第一次版本号\t"+stamp);
            stampedReference.compareAndSet(100,101,stamp,stamp+1);
            System.out.println("t3--->第二次版本号\t"+stampedReference.getStamp());
            stampedReference.compareAndSet(101,100,stampedReference.getStamp(),stampedReference.getStamp()+1);
            System.out.println("t3--->第三次版本号\t"+stampedReference.getStamp());

        },"t3").start();

        new Thread(()->{
            int stamp = stampedReference.getStamp();
            try { Thread.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            System.out.println("t4-->第一次版本号\t"+stamp);
            boolean result = stampedReference.compareAndSet(100, 2020, stamp, stamp + 1);
            System.out.println("t4-->是否修改成功\t"+result);
            System.out.println("t4-->当前最新班版号\t"+stampedReference.getStamp());
        },"t4").start();
    }
}
